package com.jrx.anytxn.transaction.job.dailyAccount.step;

import com.jrx.anytxn.common.uitl.StringUtils;
import com.jrx.anytxn.feign.common.GateWayPredicate;
import com.jrx.anytxn.feign.gateway.response.CoreResponse16;
import com.jrx.anytxn.feign.gateway.service.IInnerGatewayService;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlDailyAccountLog;
import com.jrx.anytxn.transaction.entity.TlDisbursementLog;
import com.jrx.anytxn.transaction.job.dailyAccount.bean.DailyAccountBean;
import com.jrx.anytxn.transaction.enums.DailyAccountEnum;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlDailyAccountLogMapper;
import com.jrx.anytxn.transaction.mapper.ext.ExtTlDisbursementLogMapper;
import com.jrx.anytxn.transaction.pojo.DailyAccount;
import com.jrx.anytxn.transaction.service.IDealGatewayService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 日终T24核心汇总记账 记账状态更新数据组装
 *
 * @Author yhy
 * @Date 2023/4/29 15:29
 */
@Service
public class DailyAccountStatusUpdateProcessor implements ItemProcessor<TlDailyAccountLog, DailyAccountBean> {

    private final Logger logger = LoggerFactory.getLogger(DailyAccountStatusUpdateProcessor.class);

    @Lazy
    @Autowired
    private IInnerGatewayService innerGatewayService;

    @Autowired
    private IDealGatewayService dealGatewayService;

    @Resource
    private ExtTlDisbursementLogMapper extTlDisbursementLogMapper;

    @Resource
    private ExtTlDailyAccountLogMapper extTlDailyAccountLogMapper;

    @Override
    public DailyAccountBean process(TlDailyAccountLog item) throws Exception {
        try {
            // 贷方介质账号码值
            String creditMediumAcctCode = null;
            // 获取兴安借-他行卡放款内部账户-大小额渠道
            if (DailyAccountEnum.T24_CHANNEL_BEPS_HVPS.getCode().contains(item.getSettleChannel())){
                creditMediumAcctCode = TransBizConstant.OUTER_BANK_DISBURSE_LS_ACCT;
            }
            // 获取兴安借-他行卡放款内部账户-超级网银渠道
            if (DailyAccountEnum.T24_CHANNEL_IBPS.getCode().contains(item.getSettleChannel())){
                creditMediumAcctCode = TransBizConstant.OUTER_BANK_DISBURSE_SUPER_ACCT;
            }

            DailyAccountBean dailyAccountBean = new DailyAccountBean();
            // 判断借方介质账号码值是否为空
            if (StringUtils.isNotBlank(creditMediumAcctCode)){
                // 发起日终T24核心汇总记账查询
                dailyAccountBean = this.queryInterestCompensateT24(item, creditMediumAcctCode);
            }
            return dailyAccountBean;
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("DailyAccountStatusUpdateProcessor 出错了：{}", e);
        }
        return null;
    }

    /**
     * 日终T24核心汇总记账
     * @param record 记账明细信息
     * @param creditMediumAcctCode 贷方介质账号码值
     * @return
     * @throws Exception
     */
    private DailyAccountBean queryInterestCompensateT24(TlDailyAccountLog record, String creditMediumAcctCode) throws Exception{
        // 构建日终T24核心汇总记账请求信息
        DailyAccount dailyAccount = new DailyAccount();
        dailyAccount.setTenantId(record.getTenantId());
        dailyAccount.setTotalAmount(this.getTotalAmountBySeqNo(record.getSeqNo()));
        String coreRequest16Json = dealGatewayService.buildT24Req(dailyAccount, creditMediumAcctCode, record.getSeqNo());
        // 调用日终T24核心汇总记账
        GateWayPredicate<CoreResponse16> core16Pre = () -> innerGatewayService.interestCompensate(coreRequest16Json);
        CoreResponse16 res = null;
        try {
            res = core16Pre.getRes(core16Pre);
        } catch (Exception e) {
            logger.error("调用日终T24核心汇总记账查询接口出现异常", e);
        }

        String transactionId = null;
        String busCode = null;
        String busMsg = null;
        String result = TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O;
        if (!ObjectUtils.isEmpty(res)){
            result = res.getDealState();
            busCode = res.getBusCode();
            busMsg = res.getBusMsg();
            transactionId = res.getTransactionId25();
            if (TransBizConstant.GATEWAY_DEAL_SUC.equals(result)) { //成功
                result = TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_S;
            } else if (TransBizConstant.GATEWAY_DEAL_FAIL.equals(result)) {//失败
                result = TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_F;
            }
        }
        return this.buildDailyAccountBean(record.getSeqNo(), result, busCode, busMsg, transactionId);
    }

    /**
     * 构建日终T24核心汇总记账处理对象
     * @param seqNo 记账请求流水号
     * @param result 交易状态
     * @param busCode 交易返回码
     * @param busMsg 交易返回信息
     * @param transactionId 交易参考号(核心/支付返回)
     * @return
     */
    private DailyAccountBean buildDailyAccountBean(String seqNo, String result, String busCode, String busMsg, String transactionId){
        DailyAccountBean dailyAccountBean = new DailyAccountBean();
        // 1.判断记账状态为明确状态 S-成功，F-失败;   O-未知状态不做处理
        if(!TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O.equals(result)){
            // 2.构建日终T24核心汇总记账明细
            List<TlDailyAccountLog> accountLogList = new ArrayList<>();
            TlDailyAccountLog accountLog = this.buildTlDailyAccountLog(seqNo, result, busCode, busMsg, transactionId);
            accountLogList.add(accountLog);

            // 2.构建放款流水记账信息
            List<TlDisbursementLog> disLogList = new ArrayList<>();
            this.buildTlDisbursementLog(disLogList, seqNo, result);

            // 4.组装待处理list
            dailyAccountBean.setTlDailyAccountLogList(accountLogList);
            dailyAccountBean.setTlDisbursementLogList(disLogList);
        }
        return dailyAccountBean;
    }

    /**
     * 构建日终T24核心汇总记账明细
     * @param seqNo 记账请求流水号
     * @param result 交易状态
     * @param busCode 交易返回码
     * @param busMsg 交易返回信息
     * @param transactionId 交易参考号(核心/支付返回)
     * @return
     */
    private TlDailyAccountLog buildTlDailyAccountLog(String seqNo, String result, String busCode, String busMsg, String transactionId){
        TlDailyAccountLog accountLog = new TlDailyAccountLog();
        // 请求流水号
        accountLog.setSeqNo(seqNo);
        // 交易参考号(核心/支付返回)
        accountLog.setTransactionId(transactionId);
        // 交易返回码
        accountLog.setReturnCode(busCode);
        // 交易返回信息
        accountLog.setReturnMsg(busMsg);
        // 交易状态
        accountLog.setReturnStatus(result);
        accountLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
        accountLog.setRecordVersionNumber(TransBizConstant.INIT_RECORD_VERSION_NUMBER);
        return accountLog;
    }

    /**
     * 构建放款流水记账信息
     * @param disLogList 待组装放款流水列表
     * @param seqNo 记账请求流水号
     * @param result 记账状态
     * @return
     */
    private List<TlDisbursementLog> buildTlDisbursementLog(List<TlDisbursementLog> disLogList, String seqNo, String result){
        // 通过记账交易流水号查询记账明细数据
        List<TlDailyAccountLog> tlDailyAccountLogList = extTlDailyAccountLogMapper.selectBySeqNo(seqNo);
        if (CollectionUtils.isNotEmpty(tlDailyAccountLogList)){
            for (TlDailyAccountLog dailyAccountLog : tlDailyAccountLogList){
                // 通过记账流水表中放款流水表ID查询放款流水记录
                TlDisbursementLog disbursementLog = extTlDisbursementLogMapper.selectByPrimaryKey(dailyAccountLog.getDisId());
                // 判断放款流水表中日终记账状态为 O-未知时做处理
                if(TransBizConstant.DISBURSEMENT_LOG_SUM_STATUS_O.equals(disbursementLog.getKeepAccountStatus())){
                    TlDisbursementLog updateLog = new TlDisbursementLog();
                    // 设置主键
                    updateLog.setId(disbursementLog.getId());
                    // 日终T24核心汇总记账状态 S-记账成功，F-记账失败，O-记账状态未知，默认D-未记账
                    updateLog.setKeepAccountStatus(result);
                    updateLog.setUpdateBy(TransBizConstant.SYS_OPRATE);
                    updateLog.setRecordVersionNumber(disbursementLog.getRecordVersionNumber() + 1);
                    disLogList.add(updateLog);
                }
            }
        }
        return disLogList;
    }

    /**
     * 通过记账流水号获取日终汇总记账总金额
     * @param seqNo 记账流水号
     * @return
     */
    private BigDecimal getTotalAmountBySeqNo(String seqNo){
        BigDecimal totalAmount = BigDecimal.ZERO;
        // 通过记账交易流水号查询记账明细数据
        List<TlDailyAccountLog> tlDailyAccountLogList = extTlDailyAccountLogMapper.selectBySeqNo(seqNo);
        if (CollectionUtils.isNotEmpty(tlDailyAccountLogList)){
             totalAmount = tlDailyAccountLogList.stream().map(TlDailyAccountLog::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        }
        return totalAmount;
    }
}
